{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "61cb8e46",
   "metadata": {},
   "outputs": [],
   "source": [
    "import xlearn as xl\n",
    "import numpy as np\n",
    "import xlearn as xl\n",
    "from sklearn.datasets import load_iris\n",
    "from sklearn.model_selection import train_test_split\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "0cf77c22",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Unnamed: 0</th>\n",
       "      <th>android_id</th>\n",
       "      <th>apptype</th>\n",
       "      <th>carrier</th>\n",
       "      <th>dev_height</th>\n",
       "      <th>dev_ppi</th>\n",
       "      <th>dev_width</th>\n",
       "      <th>label</th>\n",
       "      <th>lan</th>\n",
       "      <th>media_id</th>\n",
       "      <th>...</th>\n",
       "      <th>os</th>\n",
       "      <th>osv</th>\n",
       "      <th>package</th>\n",
       "      <th>sid</th>\n",
       "      <th>timestamp</th>\n",
       "      <th>version</th>\n",
       "      <th>fea_hash</th>\n",
       "      <th>location</th>\n",
       "      <th>fea1_hash</th>\n",
       "      <th>cus_type</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>316361</td>\n",
       "      <td>1199</td>\n",
       "      <td>46000.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>104</td>\n",
       "      <td>...</td>\n",
       "      <td>android</td>\n",
       "      <td>9</td>\n",
       "      <td>18</td>\n",
       "      <td>1438873</td>\n",
       "      <td>1.559893e+12</td>\n",
       "      <td>8</td>\n",
       "      <td>2135019403</td>\n",
       "      <td>0</td>\n",
       "      <td>2329670524</td>\n",
       "      <td>601</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>135939</td>\n",
       "      <td>893</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>19</td>\n",
       "      <td>...</td>\n",
       "      <td>android</td>\n",
       "      <td>8.1</td>\n",
       "      <td>0</td>\n",
       "      <td>1185582</td>\n",
       "      <td>1.559994e+12</td>\n",
       "      <td>4</td>\n",
       "      <td>2782306428</td>\n",
       "      <td>1</td>\n",
       "      <td>2864801071</td>\n",
       "      <td>1000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>399254</td>\n",
       "      <td>821</td>\n",
       "      <td>0.0</td>\n",
       "      <td>760.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>360.0</td>\n",
       "      <td>1</td>\n",
       "      <td>NaN</td>\n",
       "      <td>559</td>\n",
       "      <td>...</td>\n",
       "      <td>android</td>\n",
       "      <td>8.1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1555716</td>\n",
       "      <td>1.559837e+12</td>\n",
       "      <td>0</td>\n",
       "      <td>1392806005</td>\n",
       "      <td>2</td>\n",
       "      <td>628911675</td>\n",
       "      <td>696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>68983</td>\n",
       "      <td>1004</td>\n",
       "      <td>46000.0</td>\n",
       "      <td>2214.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1080.0</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>129</td>\n",
       "      <td>...</td>\n",
       "      <td>android</td>\n",
       "      <td>8.1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1093419</td>\n",
       "      <td>1.560042e+12</td>\n",
       "      <td>0</td>\n",
       "      <td>3562553457</td>\n",
       "      <td>3</td>\n",
       "      <td>1283809327</td>\n",
       "      <td>753</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>288999</td>\n",
       "      <td>1076</td>\n",
       "      <td>46000.0</td>\n",
       "      <td>2280.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1080.0</td>\n",
       "      <td>1</td>\n",
       "      <td>zh-CN</td>\n",
       "      <td>64</td>\n",
       "      <td>...</td>\n",
       "      <td>android</td>\n",
       "      <td>8.0.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1400089</td>\n",
       "      <td>1.559867e+12</td>\n",
       "      <td>5</td>\n",
       "      <td>2364522023</td>\n",
       "      <td>4</td>\n",
       "      <td>1510695983</td>\n",
       "      <td>582</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>499995</th>\n",
       "      <td>499995</td>\n",
       "      <td>392477</td>\n",
       "      <td>1028</td>\n",
       "      <td>46000.0</td>\n",
       "      <td>1920.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1080.0</td>\n",
       "      <td>1</td>\n",
       "      <td>zh-CN</td>\n",
       "      <td>144</td>\n",
       "      <td>...</td>\n",
       "      <td>Android</td>\n",
       "      <td>7.1.2</td>\n",
       "      <td>25</td>\n",
       "      <td>1546078</td>\n",
       "      <td>1.559834e+12</td>\n",
       "      <td>7</td>\n",
       "      <td>861755946</td>\n",
       "      <td>79</td>\n",
       "      <td>140647032</td>\n",
       "      <td>373</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>499996</th>\n",
       "      <td>499996</td>\n",
       "      <td>346134</td>\n",
       "      <td>1001</td>\n",
       "      <td>0.0</td>\n",
       "      <td>1424.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>720.0</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>29</td>\n",
       "      <td>...</td>\n",
       "      <td>android</td>\n",
       "      <td>8.1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>1480612</td>\n",
       "      <td>1.559814e+12</td>\n",
       "      <td>3</td>\n",
       "      <td>1714444511</td>\n",
       "      <td>23</td>\n",
       "      <td>2745131047</td>\n",
       "      <td>525</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>499997</th>\n",
       "      <td>499997</td>\n",
       "      <td>499635</td>\n",
       "      <td>761</td>\n",
       "      <td>46000.0</td>\n",
       "      <td>1280.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>720.0</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>54</td>\n",
       "      <td>...</td>\n",
       "      <td>android</td>\n",
       "      <td>6.0.1</td>\n",
       "      <td>9</td>\n",
       "      <td>1698442</td>\n",
       "      <td>1.559676e+12</td>\n",
       "      <td>0</td>\n",
       "      <td>3843262581</td>\n",
       "      <td>25</td>\n",
       "      <td>1326115882</td>\n",
       "      <td>810</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>499998</th>\n",
       "      <td>499998</td>\n",
       "      <td>239786</td>\n",
       "      <td>917</td>\n",
       "      <td>46001.0</td>\n",
       "      <td>960.0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>540.0</td>\n",
       "      <td>0</td>\n",
       "      <td>zh_CN</td>\n",
       "      <td>109</td>\n",
       "      <td>...</td>\n",
       "      <td>android</td>\n",
       "      <td>5.1.1</td>\n",
       "      <td>0</td>\n",
       "      <td>1331155</td>\n",
       "      <td>1.559840e+12</td>\n",
       "      <td>0</td>\n",
       "      <td>1984296118</td>\n",
       "      <td>225</td>\n",
       "      <td>1446741112</td>\n",
       "      <td>772</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>499999</th>\n",
       "      <td>499999</td>\n",
       "      <td>270531</td>\n",
       "      <td>929</td>\n",
       "      <td>46000.0</td>\n",
       "      <td>2040.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1080.0</td>\n",
       "      <td>1</td>\n",
       "      <td>zh-CN</td>\n",
       "      <td>59</td>\n",
       "      <td>...</td>\n",
       "      <td>Android</td>\n",
       "      <td>8.1.0</td>\n",
       "      <td>78</td>\n",
       "      <td>1373973</td>\n",
       "      <td>1.559922e+12</td>\n",
       "      <td>5</td>\n",
       "      <td>1697301943</td>\n",
       "      <td>49</td>\n",
       "      <td>1915763579</td>\n",
       "      <td>1076</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>500000 rows × 21 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "        Unnamed: 0  android_id  apptype  carrier  dev_height  dev_ppi  \\\n",
       "0                0      316361     1199  46000.0         0.0      0.0   \n",
       "1                1      135939      893      0.0         0.0      0.0   \n",
       "2                2      399254      821      0.0       760.0      0.0   \n",
       "3                3       68983     1004  46000.0      2214.0      0.0   \n",
       "4                4      288999     1076  46000.0      2280.0      0.0   \n",
       "...            ...         ...      ...      ...         ...      ...   \n",
       "499995      499995      392477     1028  46000.0      1920.0      3.0   \n",
       "499996      499996      346134     1001      0.0      1424.0      0.0   \n",
       "499997      499997      499635      761  46000.0      1280.0      0.0   \n",
       "499998      499998      239786      917  46001.0       960.0      0.0   \n",
       "499999      499999      270531      929  46000.0      2040.0      3.0   \n",
       "\n",
       "        dev_width  label    lan  media_id  ...       os    osv package  \\\n",
       "0             0.0      1    NaN       104  ...  android      9      18   \n",
       "1             0.0      1    NaN        19  ...  android    8.1       0   \n",
       "2           360.0      1    NaN       559  ...  android  8.1.0       0   \n",
       "3          1080.0      0    NaN       129  ...  android  8.1.0       0   \n",
       "4          1080.0      1  zh-CN        64  ...  android  8.0.0       0   \n",
       "...           ...    ...    ...       ...  ...      ...    ...     ...   \n",
       "499995     1080.0      1  zh-CN       144  ...  Android  7.1.2      25   \n",
       "499996      720.0      0    NaN        29  ...  android  8.1.0       0   \n",
       "499997      720.0      0    NaN        54  ...  android  6.0.1       9   \n",
       "499998      540.0      0  zh_CN       109  ...  android  5.1.1       0   \n",
       "499999     1080.0      1  zh-CN        59  ...  Android  8.1.0      78   \n",
       "\n",
       "            sid     timestamp  version    fea_hash location   fea1_hash  \\\n",
       "0       1438873  1.559893e+12        8  2135019403        0  2329670524   \n",
       "1       1185582  1.559994e+12        4  2782306428        1  2864801071   \n",
       "2       1555716  1.559837e+12        0  1392806005        2   628911675   \n",
       "3       1093419  1.560042e+12        0  3562553457        3  1283809327   \n",
       "4       1400089  1.559867e+12        5  2364522023        4  1510695983   \n",
       "...         ...           ...      ...         ...      ...         ...   \n",
       "499995  1546078  1.559834e+12        7   861755946       79   140647032   \n",
       "499996  1480612  1.559814e+12        3  1714444511       23  2745131047   \n",
       "499997  1698442  1.559676e+12        0  3843262581       25  1326115882   \n",
       "499998  1331155  1.559840e+12        0  1984296118      225  1446741112   \n",
       "499999  1373973  1.559922e+12        5  1697301943       49  1915763579   \n",
       "\n",
       "        cus_type  \n",
       "0            601  \n",
       "1           1000  \n",
       "2            696  \n",
       "3            753  \n",
       "4            582  \n",
       "...          ...  \n",
       "499995       373  \n",
       "499996       525  \n",
       "499997       810  \n",
       "499998       772  \n",
       "499999      1076  \n",
       "\n",
       "[500000 rows x 21 columns]"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 数据加载\n",
    "train = pd.read_csv('./train.csv')\n",
    "test = pd.read_csv('./test.csv')\n",
    "train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "db019dad",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 处理osv\n",
    "def trans_osv(osv):\n",
    "    global result\n",
    "    osv = str(osv).replace(' ','').replace('.','').replace('Android_','').replace('十核20G_HD','').replace('Android','').replace('W','')\n",
    "    if osv == 'nan' or osv == 'GIONEE_YNGA':\n",
    "        result = 810\n",
    "    elif osv.count('-') >0:\n",
    "        result = int(osv.split('-')[0])\n",
    "    elif osv == 'f073b_changxiang_v01_b1b8_20180915':\n",
    "        result = 810\n",
    "    elif osv == '%E6%B1%9F%E7%81%B5OS+50':\n",
    "        result = 500\n",
    "    else:\n",
    "        result = int(osv)\n",
    "        \n",
    "    if result < 10:\n",
    "        result = result * 100\n",
    "    elif  result < 100:\n",
    "        result = result * 10\n",
    "        \n",
    "    return int(result)\n",
    "# 转化app版本号\n",
    "def trans_version(version):\n",
    "    version = version.replace('V','').replace('P_Final_','').replace(' ','').replace('GA','').replace('v','')\n",
    "    if version == '50':\n",
    "        return int(5)\n",
    "    return int(version)\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "37396234",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 对语言进行文字化处理\n",
    "lan_dict = {'zh_CN':1,'zh-CN':2,'zh-cn':3,'Zh-CN':4,'ZH':5,'zh':6,'cn':7,'CN':8,'zh_CN_#Hans':9,'zh-HK':10,'zh-MO':11,'zh-TW':12,'tw':13,'TW':14,'en':15,'en-GB':16,'en-US':17,'ja':18,'mi':19,'ko':20,'it':21,'nan':22}\n",
    "train['lan'] = train['lan'].map(lan_dict) \n",
    "train['lan'] = train['lan'].fillna(22)\n",
    "\n",
    "test['lan'] = test['lan'].map(lan_dict) \n",
    "test['lan'] = test['lan'].fillna(22)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "fc70da17",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 获取训练特征\n",
    "features = train.columns.tolist()\n",
    "features.remove('label')\n",
    "\n",
    "remove_list = ['os', 'sid', 'Unnamed: 0']\n",
    "col = features\n",
    "for i in remove_list:\n",
    "    col.remove(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "c8426e84",
   "metadata": {},
   "outputs": [],
   "source": [
    "from datetime import datetime\n",
    "# 特征筛选\n",
    "features = train[col]\n",
    "# 构造fea_hash_len特征\n",
    "features['fea_hash_len'] = features['fea_hash'].map(lambda x: len(str(x)))\n",
    "features['fea1_hash_len'] = features['fea1_hash'].map(lambda x: len(str(x)))\n",
    "# Thinking：为什么将很大的，很长的fea_hash化为0？\n",
    "# 如果fea_hash很长，都归为0，否则为自己的本身\n",
    "features['fea_hash'] = features['fea_hash'].map(lambda x: 0 if len(str(x))>16 else int(x))\n",
    "features['fea1_hash'] = features['fea1_hash'].map(lambda x: 0 if len(str(x))>16 else int(x))\n",
    "\n",
    "\n",
    "features['osv'] = features['osv'].apply(trans_osv)\n",
    "features['version'] = features['version'].apply(trans_version)\n",
    "\n",
    "features['timestamp'] = features['timestamp'].apply(lambda x : datetime.fromtimestamp(x/1000))\n",
    "# 分解时间\n",
    "features['year'] = features['timestamp'].dt.year\n",
    "features['month'] = features['timestamp'].dt.month\n",
    "features['day'] = features['timestamp'].dt.day\n",
    "features['weekday'] = features['timestamp'].dt.weekday\n",
    "features['hour'] = features['timestamp'].dt.hour\n",
    "features['minute'] = features['timestamp'].dt.minute\n",
    "# 获取time_diff\n",
    "start_time = features['timestamp'].min()\n",
    "features['timestamp_diff'] = features['timestamp']-start_time\n",
    "features['timestamp_diff'] = features['timestamp_diff'].dt.days - features['timestamp_diff'].dt.seconds/3600/24\n",
    "\n",
    "# 对版本进行处理\n",
    "features['osv1'] = features['osv'] - features['version'] \n",
    "\n",
    "features['type'] = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "f08aa7f9",
   "metadata": {},
   "outputs": [],
   "source": [
    "test_features = test[col]\n",
    "# 构造fea_hash_len特征\n",
    "test_features['fea_hash_len'] = test_features['fea_hash'].map(lambda x: len(str(x)))\n",
    "test_features['fea1_hash_len'] = test_features['fea1_hash'].map(lambda x: len(str(x)))\n",
    "# Thinking：为什么将很大的，很长的fea_hash化为0？\n",
    "# 如果fea_hash很长，都归为0，否则为自己的本身\n",
    "test_features['fea_hash'] = test_features['fea_hash'].map(lambda x: 0 if len(str(x))>16 else int(x))\n",
    "test_features['fea1_hash'] = test_features['fea1_hash'].map(lambda x: 0 if len(str(x))>16 else int(x))\n",
    "\n",
    "test_features['osv'] = test_features['osv'].apply(trans_osv)\n",
    "test_features['version'] = test_features['version'].apply(trans_version)\n",
    "\n",
    "test_features['timestamp'] = test_features['timestamp'].apply(lambda x : datetime.fromtimestamp(x/1000))\n",
    "# 分解时间\n",
    "test_features['year'] = test_features['timestamp'].dt.year\n",
    "test_features['month'] = test_features['timestamp'].dt.month\n",
    "test_features['day'] = test_features['timestamp'].dt.day\n",
    "test_features['weekday'] = test_features['timestamp'].dt.weekday\n",
    "test_features['hour'] = test_features['timestamp'].dt.hour\n",
    "test_features['minute'] = test_features['timestamp'].dt.minute\n",
    "# 获取time_diff\n",
    "start_time = features['timestamp'].min()\n",
    "test_features['timestamp_diff'] = test_features['timestamp']-start_time\n",
    "test_features['timestamp_diff'] = test_features['timestamp_diff'].dt.days - test_features['timestamp_diff'].dt.seconds/3600/24\n",
    "\n",
    "# test_features['lan'] = test_features['lan'].apply(trans_lan)\n",
    "test_features['osv1'] = test_features['osv'] - test_features['version'] \n",
    "test_features['type'] = 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "9696b2db",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义需onehot特征\n",
    "onehot_cols = ['carrier', 'lan', 'ntt', 'version', 'cus_type']\n",
    "\n",
    "full_df = pd.concat([features,test_features])\n",
    "full_df[onehot_cols] = full_df[onehot_cols].astype('str')\n",
    "data_dummies = pd.get_dummies(full_df)\n",
    "features = data_dummies[data_dummies['type'] == 1]\n",
    "test_features = data_dummies[data_dummies['type'] == 2]\n",
    "\n",
    "features = features.drop(['type','timestamp'], axis=1)\n",
    "test_features = test_features.drop(['type','timestamp'], axis=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "id": "aa85941b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on class FMModel in module xlearn._sklearn:\n",
      "\n",
      "class FMModel(BaseXLearnModel)\n",
      " |  FMModel(model_type='fm', task='binary', metric='auc', block_size=500, lr=0.2, k=4, reg_lambda=0.1, init=0.1, fold=1, epoch=5, stop_window=2, opt='sgd', nthread=None, n_jobs=4, alpha=1, beta=1, lambda_1=1, lambda_2=1, seed=1, **kwargs)\n",
      " |  \n",
      " |  Factorization machine (FM) model\n",
      " |  \n",
      " |  Method resolution order:\n",
      " |      FMModel\n",
      " |      BaseXLearnModel\n",
      " |      sklearn.base.BaseEstimator\n",
      " |      builtins.object\n",
      " |  \n",
      " |  Methods defined here:\n",
      " |  \n",
      " |  __delete__(self, instance)\n",
      " |  \n",
      " |  __init__(self, model_type='fm', task='binary', metric='auc', block_size=500, lr=0.2, k=4, reg_lambda=0.1, init=0.1, fold=1, epoch=5, stop_window=2, opt='sgd', nthread=None, n_jobs=4, alpha=1, beta=1, lambda_1=1, lambda_2=1, seed=1, **kwargs)\n",
      " |      Initialize self.  See help(type(self)) for accurate signature.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from BaseXLearnModel:\n",
      " |  \n",
      " |  __del__(self)\n",
      " |  \n",
      " |  feature_importance_(self)\n",
      " |      TODO: analyze weight matrix to get feature importance\n",
      " |  \n",
      " |  fit(self, X, y=None, fields=None, is_lock_free=True, is_instance_norm=True, eval_set=None, is_quiet=False)\n",
      " |      Fit the XLearn model given feature matrix X and label y\n",
      " |      \n",
      " |      :param X: array-like or a string specifying file location\n",
      " |                Feature matrix\n",
      " |      :param y: array-like\n",
      " |                Label\n",
      " |      :param fields: array-like\n",
      " |                Fields for FFMModel. Default as None\n",
      " |      :param is_lock_free: is using lock-free training\n",
      " |      :param is_instance_norm: is using instance-wise normalization\n",
      " |      :param eval_set: a 2-element list representing (X_val, y_val) or a string specifying file location\n",
      " |      :param is_quiet: is training model quietly\n",
      " |  \n",
      " |  get_model(self)\n",
      " |      Return internal XLearn model.\n",
      " |      \n",
      " |      This will raise exception when model is not fitted\n",
      " |      \n",
      " |      :return: the underlying XLearn model\n",
      " |  \n",
      " |  get_params(self, deep=False)\n",
      " |      Get model parameters\n",
      " |      \n",
      " |      :param deep: is deep copy\n",
      " |      :return: model parameters\n",
      " |  \n",
      " |  get_xlearn_params(self)\n",
      " |      Get xlearn model parameters\n",
      " |      \n",
      " |      :return: model parameters used for training\n",
      " |  \n",
      " |  predict(self, X)\n",
      " |      Generate prediction using feature matrix X\n",
      " |      \n",
      " |      :param X: array-like\n",
      " |                Feature matrix\n",
      " |      :return: prediction\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Methods inherited from sklearn.base.BaseEstimator:\n",
      " |  \n",
      " |  __getstate__(self)\n",
      " |  \n",
      " |  __repr__(self, N_CHAR_MAX=700)\n",
      " |      Return repr(self).\n",
      " |  \n",
      " |  __setstate__(self, state)\n",
      " |  \n",
      " |  set_params(self, **params)\n",
      " |      Set the parameters of this estimator.\n",
      " |      \n",
      " |      The method works on simple estimators as well as on nested objects\n",
      " |      (such as :class:`~sklearn.pipeline.Pipeline`). The latter have\n",
      " |      parameters of the form ``<component>__<parameter>`` so that it's\n",
      " |      possible to update each component of a nested object.\n",
      " |      \n",
      " |      Parameters\n",
      " |      ----------\n",
      " |      **params : dict\n",
      " |          Estimator parameters.\n",
      " |      \n",
      " |      Returns\n",
      " |      -------\n",
      " |      self : estimator instance\n",
      " |          Estimator instance.\n",
      " |  \n",
      " |  ----------------------------------------------------------------------\n",
      " |  Data descriptors inherited from sklearn.base.BaseEstimator:\n",
      " |  \n",
      " |  __dict__\n",
      " |      dictionary for instance variables (if defined)\n",
      " |  \n",
      " |  __weakref__\n",
      " |      list of weak references to the object (if defined)\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(xl.FMModel)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "25df2813",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1., 1., 0., ..., 1., 1., 1.], dtype=float32)"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "fm_model = xl.FMModel(lr=0.01,epoch=30)\n",
    "\n",
    "X_train, X_val, y_train, y_val = train_test_split(features, train['label'], test_size=0.3, random_state=0)\n",
    "fm_model.fit(X_train, y_train,\n",
    "                 eval_set=[X_val, y_val],\n",
    "                 is_lock_free=False)\n",
    "y_pred = linear_model.predict(test_features)\n",
    "y_pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "id": "ad377c9d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>sid</th>\n",
       "      <th>label</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1440682</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1606824</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>1774642</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>1742535</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1689686</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149995</th>\n",
       "      <td>1165373</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149996</th>\n",
       "      <td>1444115</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149997</th>\n",
       "      <td>1134378</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149998</th>\n",
       "      <td>1700238</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>149999</th>\n",
       "      <td>1201539</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>150000 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "            sid  label\n",
       "0       1440682    1.0\n",
       "1       1606824    1.0\n",
       "2       1774642    0.0\n",
       "3       1742535    1.0\n",
       "4       1689686    1.0\n",
       "...         ...    ...\n",
       "149995  1165373    1.0\n",
       "149996  1444115    1.0\n",
       "149997  1134378    1.0\n",
       "149998  1700238    1.0\n",
       "149999  1201539    1.0\n",
       "\n",
       "[150000 rows x 2 columns]"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#features['version'].value_counts()\n",
    "res = pd.DataFrame(test['sid'])\n",
    "res['label'] = y_pred\n",
    "# res.to_csv('./result/fm_20211223_1.csv', index=False)\n",
    "res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d34e36be",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
